<template>
  <div class="mu-scroll-wrapper">
    <div
      ref="wrapper"
      class="box"
      :style="{ maxHeight: scroll.y + 'px', maxWidth: scroll.x + 'px' }"
    >
      <slot></slot>
    </div>
    <div
      class="bar-y"
      ref="scrollY"
      v-if="scrollY.height"
      :style="{ height: scrollY.height + 'px' }"
    ></div>
  </div>
</template>

<script>
import { addEventListener, removeEventListener } from "../utils/events";
export default {
  name: "mu-scroll",
  data() {
    return {
      scrollY: { rate: 0, height: 1 }, // Y轴相关设置
    };
  },
  methods: {
    // 鼠标按下
    mousedown({ screenY }) {
      const top = this.$refs.wrapper.scrollTop;
      const mousemove = (e) => {
        e.preventDefault();
        this.$refs.wrapper.scrollTop =
          top + (e.screenY - screenY) / this.scrollY.rate;
      };

      const mouseup = (e) => {
        removeEventListener(document, "mouseup", mouseup);
        removeEventListener(document, "mousemove", mousemove);
      };
      addEventListener(document, "mouseup", mouseup);
      addEventListener(document, "mousemove", mousemove);
    },
    // scroll事件
    wrapperScroll(e) {
      this.$refs.scrollY.style.top =
        this.$refs.wrapper.scrollTop * this.scrollY.rate + "px";
    },
    // 计算Y轴
    calcY() {
      const clientHeight = this.$refs.wrapper.clientHeight;
      const scrollHeight = this.$refs.wrapper.scrollHeight;
      this.scrollY.rate = clientHeight / scrollHeight;
      if (this.scrollY.rate >= 1) {
        this.scrollY.height = 0;
        return;
      }
      this.scrollY.height = clientHeight * this.scrollY.rate;
    },
  },
  mounted() {
    this.calcY();
    addEventListener(this.$refs.wrapper, "scroll", this.wrapperScroll);
    addEventListener(this.$refs.scrollY, "mousedown", this.mousedown);
  },
  updated() {
    this.calcY();
  },
  // 销毁
  beforeDestroy() {
    removeEventListener(this.$refs.wrapper, "scroll", this.wrapperScroll);
    removeEventListener(this.$refs.scrollY, "mousedown", this.mousedown);
  },
  props: {
    // 滚动参数
    scroll: {
      type: Object,
      default() {
        return {
          x: false,
          y: false,
        };
      },
    },
  },
};
</script>

<style lang="scss" scoped>
div {
  padding: 0;
  margin: 0;
}

.mu-scroll-wrapper {
  overflow: hidden;
  position: relative;

  .box {
    overflow: scroll;
    margin-right: -17px;
    margin-bottom: -17px;
  }

  &:hover {
    [class*="bar-"],
    [class^="bar-"] {
      opacity: 1;
    }
  }

  [class*="bar-"],
  [class^="bar-"] {
    opacity: 0;
    cursor: pointer;
    border-radius: 15px;
    position: absolute;
    background: rgba(144, 147, 153, 0.3);
    transition: background 0.3s, opacity 0.3s;

    &:hover {
      background: rgb(144, 147, 153);
    }
  }

  .bar-y {
    top: 0;
    width: 6px;
    right: 1px;
    will-change: top;
  }

  .bar-x {
    height: 6px;
    left: 0;
    bottom: 1px;
    will-change: left;
  }
}
</style>